﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace WinServiceKeepAlive
{
    public static class ExtObject
    {
        public static string ToString2(this object source)
        {
            if (source == null || source == DBNull.Value)
            {
                return string.Empty;
            }

            return source.ToString();
        }

        public static int ToInt32(this object source)
        {
            return source.ToInt32(0);
        }

        public static int ToInt32(this object source, int defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            int result = 0;
            if (int.TryParse(source.ToString(), out result))
            {
                return result;
            }

            return defaultValue;
        }

        public static long ToInt64(this object source)
        {
            return source.ToInt64(0);
        }

        public static long ToInt64(this object source, int defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            long result = 0L;
            if (long.TryParse(source.ToString(), out result))
            {
                return result;
            }

            return defaultValue;
        }

        public static double ToDouble(this object source)
        {
            return source.ToDouble(0.0);
        }

        public static double ToDouble(this object source, double defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            double result = 0.0;
            if (double.TryParse(source.ToString(), out result))
            {
                return result;
            }

            return defaultValue;
        }

        public static float ToFloat(this object source, float defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            float result = 0f;
            if (float.TryParse(source.ToString(), out result))
            {
                return result;
            }

            return defaultValue;
        }

        public static Guid? ToGuid(this object source, Guid? defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            try
            {
                return new Guid(source.ToString());
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        public static Guid? ToGuid(this object source)
        {
            return source.ToGuid(null);
        }

        public static DateTime ToDateTime(this object source, DateTime defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            DateTime result = defaultValue;
            if (DateTime.TryParse(source.ToString(), out result))
            {
                return result;
            }

            return defaultValue;
        }

        public static DateTime ToDateTime(this object source)
        {
            return source.ToDateTime(DateTime.MinValue);
        }

        public static string DateTimeParse(this object source, string format = "")
        {
            try
            {
                string result = "";
                if (source == null)
                {
                    return result;
                }

                return (!string.IsNullOrEmpty(format)) ? DateTime.Parse(source.ToString()).ToString(format) : DateTime.Parse(source.ToString()).ToString();
            }
            catch (Exception)
            {
                return "";
            }
        }

        public static List<Dictionary<string, object>> ToDictionaryList(this object source)
        {
            List<Dictionary<string, object>> result = null;
            if (source != null && source != DBNull.Value)
            {
                try
                {
                    result = (List<Dictionary<string, object>>)source;
                }
                catch (Exception)
                {
                    return null;
                }
            }

            return result;
        }

        public static List<string> ToList(this object source)
        {
            List<string> result = null;
            if (source != null && source != DBNull.Value)
            {
                try
                {
                    result = (List<string>)source;
                }
                catch (Exception)
                {
                    return null;
                }
            }

            return result;
        }

        public static T DeepClone<T>(this T source) where T : class
        {
            MemoryStream memoryStream = new MemoryStream();
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, source);
            memoryStream.Position = 0L;
            return binaryFormatter.Deserialize(memoryStream) as T;
        }

        public static object GetPropertyValue(this object source, string propertyName)
        {
            Type type = source.GetType();
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                if (propertyInfo.Name.ToLower() == propertyName.ToLower())
                {
                    return propertyInfo.GetValue(source, BindingFlags.GetProperty, null, null, null);
                }
            }

            return null;
        }
    }
}
